<template>
  <div class="map-container" :="getMapOptions" />
  <div v-show="mainScreen" class="indexSelector">
    <n-select v-model:value="currentAirIndex" :options="selectOption" size="small" />
  </div>
  <!-- 网格信息 -->
  <SuqareInfo id="squareInfo" :info="squareInfo" style="z-index: 999" @close="airInfowindowClose" />
  <ColorInterval v-show="mainScreen" id="colorLegend" :air-name="airName" :air-unit="airUnit" :range="legendIndexRange" />
  <LegendIndex
    v-if="legendIndexVisible"
    id="legendIndex"
    :feature-list="newFeatureArr"
    :air-name="airName"
    :air-unit="airUnit"
    @save="changeRangeIndex"
    @close="closeRangeIndex"
  />
</template>

<script>

import { reactive, toRefs, onMounted, computed, watch, onBeforeUnmount, nextTick, watchEffect, createVNode, render, defineComponent, ref } from 'vue'

import { Map, View, Feature, Overlay } from 'ol'
import 'ol/ol.css'
import { Tile, Vector as VectorLayer } from 'ol/layer'
// import TileWMS from 'ol/source/TileWMS.js'
import LineString from 'ol/geom/LineString'
import Point from 'ol/geom/Point'
import { Style, Text, Fill } from 'ol/style'
import { XYZ, Vector as VectorSource } from 'ol/source'
import { transform, fromLonLat } from 'ol/proj'
import { getVectorContext } from 'ol/render'
import VectorContext from 'ol/render/VectorContext'
import * as control from 'ol/control'
import GeoJSON from 'ol/format/GeoJSON.js'
import * as turf from '@turf/turf'

import { styleList } from '@/utils/style.js'
// import { airportList } from '@/api/dashboard/index.js'
import gcj02Mecator from '@/utils/map/gcj02Mecator.js'
import { geomStyles } from '@/utils/map/geomStyle.js'
import { getColorByValue, getColorByRange } from '@/utils/map/AQIColorStyle.js'

import { getAirDataType, getAirtData } from '@/api/air-data/index.js'
import { getFlightData } from '@/api/flight-data/index.js'
import { routeByTask, routeByline } from '@/api/dashboard/index.js'
import axios from 'axios'
import OSS from 'ali-oss'
import { getOssAuth } from '@/api/common/upload.js'
import { exportReport } from '@/api/air-data/index.js'
import html2canvas from 'html2canvas'
import ColorInterval from './colorInterval.vue'

// import { Polygon } from 'ol/geom'
// import { feature } from '@turf/turf'
// import object from 'element-resize-detector/src/detection-strategy/object'

import SuqareInfo from './suqareInfo.vue'
import LegendIndex from './LegendIndex.vue'

export default {
  name: 'UnderLay',
  components: { LegendIndex, SuqareInfo, ColorInterval },
  props: {
    id: {
      type: String,
      default: 'underlay'
    },
    selectedInfo: {
      type: Object,
      default: () => { }
    },
    videoInfo: {
      type: Object,
      default: () => { }
    },
    gridSize: {
      type: Number,
      default: 100
    },
    legendIndex: {
      type: Boolean,
      default: false
    },
    mainScreen: {
      type: Boolean,
      default: false
    }
  },
  emits: ['distance', 'closeIndex'],
  setup(props, { emit }) {
    const data = reactive({
      map: null,
      view: null,
      drawerShow: false,
      trackLayer: null,
      trackInfo: null,
      airportLayer: null,
      // 轨迹数据
      trackList: [],
      socket: null,
      liveTrackLayer: null,
      trackTimer: null,
      airLayer: null,
      // 所有矢量图层
      vectorLayers: [],
      squareLayer: null, // 方格图层
      cellSide: 100, // 方格的边长，单位为米
      warningLngLat: [],
      squareFeatures: [], // 所有的方格feature数组
      airIndexList: [], // 所有的空气指标
      selectOption: [], // 空气指标下拉框选项
      currentAirIndex: 'pm_2_5', // 当前所选空气指标
      airLine: [],
      featureArr: [], // 最终用于绘制的网格数组
      monitorInfo: {},
      airData: null, // 所有的大气监测的点数据（包含属性数据）
      legendSrc: '',
      mountNode: null, // 弹窗挂载的dom结构
      airInfoOverlay: null, // 弹窗的地图overlay
      gridCenter: null, // 所有网格的中心点坐标
      legendIndexRange: [],
      newFeatureArr: [],
      airName: 'PM2.5',
      airUnit: 'μg/m³',
      legendIndexVisible: false,
      comparison: {
        so2: [0, 150, 500, 650, 800, 1600, '∞'],
        no2: [0, 100, 200, 700, 1200, 2340, '∞'],
        pm_10: [0, 50, 150, 250, 350, 420, '∞'],
        co: [0, 5, 10, 35, 60, 90, '∞'],
        o3: [0, 160, 200, 300, 400, 800, '∞'],
        pm_2_5: [0, 35, 75, 115, 150, 250, '∞'],
        vocs: [0, 1, 5, 10, 20, 50, '∞']
      },
      colorList: ['one', 'two', 'three', 'four', 'five', 'six'],
      mainScreen: false,
      squareInfo: null
    })

    const taskId = computed(() => props.selectedInfo.currentTask)
    const inspectionId = computed(() => props.selectedInfo.inspectionLine)
    const airport = computed(() => props.selectedInfo.currentAirport[0])
    const type = computed(() => props.selectedInfo.type)
    const inspectionType = computed(() => props.selectedInfo.inspectionType)
    const startNEnd = computed(() => props.selectedInfo.startNEnd)

    const map2Png = function() {
      const imgContext = document.getElementsByClassName('lines')[0]
      html2canvas(imgContext).then((canvas) => {
        data.legendImage = canvas.toDataURL('image/png') // 转换后的图片地址
        // console.log(data.legendImage, 164)
        if (!data.trackInfo) {
          $message.error('暂无大气数据')
        }
        setLayerVisible(data.trackInfo.vectorLayer, false)
        setLayerVisible(data.airportLayer, false)
        fitLayer(data.squareLayer)
        // data.airportLayer.setVisible(false)
        data.map.once('rendercomplete', function() {
          const mapCanvas = document.createElement('canvas')
          const size = data.map.getSize()
          mapCanvas.width = size[0]
          mapCanvas.height = size[1]
          const mapContext = mapCanvas.getContext('2d')
          Array.prototype.forEach.call(
            data.map.getViewport().querySelectorAll('.ol-layer canvas, canvas.ol-layer'),
            function(canvas) {
              if (canvas.width > 0) {
                const opacity =
                    canvas.parentNode.style.opacity || canvas.style.opacity
                mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity)
                let matrix
                const transform = canvas.style.transform
                if (transform) {
                  // Get the transform parameters from the style's transform matrix
                  matrix = transform
                    .match(/^matrix\(([^\(]*)\)$/)[1]
                    .split(',')
                    .map(Number)
                } else {
                  matrix = [
                    parseFloat(canvas.style.width) / canvas.width,
                    0,
                    0,
                    parseFloat(canvas.style.height) / canvas.height,
                    0,
                    0
                  ]
                }
                // Apply the transform to the export map context
                CanvasRenderingContext2D.prototype.setTransform.apply(
                  mapContext,
                  matrix
                )
                const backgroundColor = canvas.parentNode.style.backgroundColor
                if (backgroundColor) {
                  mapContext.fillStyle = backgroundColor
                  mapContext.fillRect(0, 0, canvas.width, canvas.height)
                }
                mapContext.drawImage(canvas, 0, 0)
              }
            }
          )
          mapContext.globalAlpha = 1
          mapContext.setTransform(1, 0, 0, 1, 0, 0)
          // 使用跨域的source图层时，比如本例中的天地图图层，要加上允许跨域的配置项 crossOrigin: 'anonymous'，否则canvas无法使用toDataURL()
          const img = mapCanvas.toDataURL()
          // upload(img)
          const imageList = [{ value: img, name: 'ossUrl' }, { value: data.legendImage, name: 'referenceIndicatorHorizontalImageUrl' }]
          console.log(data.legendImage, 1158)
          // 上传
          uploadImages(imageList)

          setLayerVisible(data.trackInfo.vectorLayer, true)
          setLayerVisible(data.airportLayer, true)
        })
        data.map.renderSync()
      })
    }

    watchEffect(() => {
      const current = data.airIndexList.filter(e => e.dataType === data.currentAirIndex)
      data.legendSrc = current[0]?.referenceIndicatorVerticalImage
      // 新增监听当前空气指数下拉框
      data.airIndexList.forEach(index => {
        if (data.currentAirIndex === index.dataType) {
          data.airName = index.name
        }
      })
    })

    watch(() => props.legendIndex, visible => {
      data.legendIndexVisible = visible
    })

    watch(() => data.featureArr, newV => {
      data.newFeatureArr = newV || []

      if (data.currentAirIndex === 'co') {
        data.airUnit = 'mg/m³'
      } else if (data.currentAirIndex === 'vocs') {
        data.airUnit = 'ppm'
      } else {
        data.airUnit = 'μg/m³'
      }
      data.airIndexList.forEach(index => {
        if (data.currentAirIndex === index.dataType) {
          data.airName = index.name
        }
      })
    }, { deep: true })

    const changeRangeIndex = (arr) => {
      data.legendIndexRange = arr || []

      // 重新绘制网格
      createSquareGrid()
      if (!data.airData) return
      airInfowindowClose()
      data.featureArr.length = 0
      data.airData.forEach(e => {
        squareFilter(e)
      })
      closeRangeIndex()
    }

    const closeRangeIndex = () => {
      emit('closeIndex')
    }

    watch(() => props.gridSize, newVal => {
      data.cellSide = newVal

      createSquareGrid()
      // 重新绘制网格
      if (!data.airData) return
      airInfowindowClose()
      // data.featureArr.forEach(e => {
      //   e.setProperties({
      //     propsArr: [],
      //     value: null,
      //     valueArr: []
      //   })
      // })
      data.featureArr.length = 0
      data.airData.forEach(e => {
        squareFilter(e)
      })
    })

    // 修改当前关注的
    watch(() => data.currentAirIndex, newV => {
      data.legendIndexRange = data.comparison[data.currentAirIndex]
      closeRangeIndex()
      createSquareGrid()
      if (!data.airData) return
      airInfowindowClose()
      // data.featureArr.forEach(e => {
      //   e.setProperties({
      //     propsArr: [],
      //     value: null,
      //     valueArr: []
      //   })
      // })
      data.featureArr.length = 0
      data.airData.forEach(e => {
        squareFilter(e)
      })
    }, { deep: true })

    // 回放时，视频与地图的联动
    watch(() => props.videoInfo, newV => {
      nextTick(() => {
        if (!data.map) {
          // getTrackData(taskId.value).then(({ trackList }) => {
          //   data.trackInfo = initTrack(formatTradeList(trackList), 'liveTrackLayer', 'route')
          // })
          data.trackInfo = initTrack(formatTradeList(data.trackList), 'liveTrackLayer', 'route')
        }
      })
    }, { deep: true, immediate: true })

    // 获取航线
    // function getAirLine() {
    //   routeByTask(taskId.value).then(res => {
    //     if (res.code !== 0) return
    //     data.airLine = res.data.data
    //     console.log('data.airLine', data.airLine);
    //     // drawDroneRoute(data.airLine)
    //     // 构建网格
    //     createSquareGrid()
    //   })
    // }

    // 根据航线id获取航线
    async function getAirLine() {
      const res = await routeByline(inspectionId.value)
      const fileUrl = res.data?.fileUrl
      return axios.get(fileUrl).then(res => {
        const lngLatsArr = []
        let lngLats = []
        if (res.status === 200) {
          const text = res.data
          let arr = text.split('\n')
          arr.shift()
          arr.pop()
          arr = arr.map((text) => {
            return text.split(/\s+/)
          })
          arr.forEach(e => {
            if (e[9] * 1 === 0 || e[8] * 1 === 0) return
            const coord = [e[9] * 1, e[8] * 1]
            lngLatsArr.push(coord)
          })
          lngLats = lngLatsArr.map(item => {
            return {
              lon: item[0],
              lat: item[1]
            }
          })
          console.log('lngLats', lngLats)

          data.airLine = lngLats
          // addAirLineLayer(lngLats)
        }
        // 构建网格
        createSquareGrid()
      })
    }

    const formatLngLat = (coord) => {
      const lngLat = []
      if (coord?.length) {
        coord.map(item => {
          lngLat.push(fromLonLat([parseFloat(item?.lng || item?.lon), parseFloat(item.lat)]))
        })
      }
      return lngLat
    }

    // 弃用
    // 构建方格2.0版本，依据点来构建，一个点一个方格
    // function createSquareByPoint(point) {
    //   // turf生成多边形圆
    //   const center = [point.longitude, point.latitude]
    //   const radius = 0.005
    //   const options = { steps: 4, unit: 'kilometer', properties: { foo: 'bar' }}
    //   const circle = turf.circle(center, radius, options)
    //   const polygon = new Polygon([circle.geometry.coordinates[0]])
    //   polygon.applyTransform(getTransform('EPSG:4326', 'EPSG:3857'))
    //   polygon.rotate(Math.PI / 4, fromLonLat(center))
    //   const features = [new Feature(polygon)]
    //   drawFeature(features)
    // }

    // 根据航线获取外接矩形
    function getBoundingBoxByLine(airLine) {
      if (!airLine) return
      let minX = airLine[0].lon
      let minY = airLine[0].lat
      let maxX = 0
      let maxY = 0
      const cellSide = data.cellSide
      // 距离转换为度数
      const degree = turf.lengthToDegrees(cellSide / 5, 'meters')
      airLine.forEach(e => {
        minX = (e.lon > minX ? minX : e.lon) * 1 - degree
        minY = (e.lat > minY ? minY : e.lat) * 1 - degree
        maxX = (e.lon < maxX ? maxX : e.lon) * 1 + degree
        maxY = (e.lat < maxY ? maxY : e.lat) * 1 + degree
        e = [e.lon, e.lat]
      })
      // 顺便获取一下所有网格的中心点
      data.gridCenter = (minX + maxX) / 2 + 'E,' + (minY + maxY) / 2 + 'N'
      const bound = [minX, minY, maxX, maxY]
      return bound
    }

    // 根据起始点获取外接矩形
    function getBoundingByPoint(points) {
      // const cellSide = data.cellSide
      const degree = turf.lengthToDegrees(1000, 'meters')
      const minX = (points[0] < points[2] ? points[0] : points[2]) * 1 - degree
      const minY = (points[1] < points[3] ? points[1] : points[3]) * 1 - degree
      const maxX = (points[0] > points[2] ? points[0] : points[2]) * 1 + degree
      const maxY = (points[1] > points[3] ? points[1] : points[3]) * 1 + degree
      data.gridCenter = (minX + maxX) / 2 + 'E,' + (minY + maxY) / 2 + 'N'
      const bound = [minX, minY, maxX, maxY]
      return bound
    }

    // 构建航线外接矩形,并划分网格
    function createSquareGrid() {
      // 任务类型: 1表示人工执飞, 2表示机场巡检
      const boundingBox = inspectionType.value === 2 ? getBoundingBoxByLine(data.airLine) : getBoundingByPoint(startNEnd.value)
      console.log('构建航线外接矩形坐标', boundingBox)
      // 默认单位平方米
      const options = { units: 'meters' }
      const squareGrid = turf.squareGrid(boundingBox, data.cellSide, options)
      console.log('返回坐标', data.cellSide)
      let collection
      if (inspectionType.value === 2) {
        // 根据航线再筛选一遍网格
        const airLineArr = []
        data.airLine.map(e => {
          const coord = [e.lon * 1, e.lat * 1]
          airLineArr.push(coord)
        })
        const tAirLine = turf.lineString(airLineArr)
        const airLineBuffer = turf.buffer(tAirLine, data.cellSide, { units: 'meters' })
        const filtratedSquare = []
        squareGrid.features.forEach((square, index) => {
          square.valueArr = []
          const intersection = turf.intersect(airLineBuffer, square)
          if (intersection) {
            filtratedSquare.push(square)
          }
        })
        collection = turf.featureCollection(filtratedSquare)
        data.squareFeatures = filtratedSquare
      }

      // data.squareFeatures = squareGrid.features
      // 画出网格线加载到map中，需要先坐标转换
      console.log('===1，走到这里', collection)
      if (collection == undefined) return
      const format = new GeoJSON()
      const olFeature = format.readFeatures(collection)// 得到结果geojson中的feature数据
      console.log('所有的方格feature数组', data.squareFeatures)
      console.log('olFeature', olFeature)

      // const olFeature = format.readFeatures(squareGrid)// 得到结果geojson中的feature数据
      console.log('得到结果geojson中的feature数据', olFeature)
      olFeature.forEach((e, index) => {
        const geom = e.getGeometry().transform('EPSG:4326', 'EPSG:3857')
        e.setGeometry(geom)
        e.setId(index)
        e.setProperties({
          id: index,
          valueArr: [],
          value: null,
          propsArr: [],
          lonArr: [],
          latArr: []
        })
      })
      drawFeature(olFeature)
    }

    // 通过无人机传回的点位来筛选具体哪些方框需要显示
    function squareFilter(point) {
      // console.log('point', point)
      // const featureArr = data.featureArr
      const pt = turf.point([point.longitude * 1, point.latitude * 1])
      data.squareFeatures.forEach((e, index) => {
        // 判断点有没有落在feature中
        const isIn = turf.booleanPointInPolygon(pt, e)
        if (isIn) {
          console.log('判断点有没有落在feature中', isIn)
          // 若点在feature中，首先获取该feature，并将该点的测值存储到feature的属性数组中
          const feature = data.featureSource.getFeatureById(index)
          // 将属性数据存储到feature的数组中
          const propsArr = feature.get('propsArr')
          propsArr.push(point)
          // 计算当前关注的测值w
          const valueArr = feature.get('valueArr')

          let i
          if (data.currentAirIndex === 'pm_2_5') {
            i = 'pm25'
          } else if (data.currentAirIndex === 'pm_10') {
            i = 'pm10'
          } else {
            i = data.currentAirIndex
          }

          valueArr.push(point[i] * 1)

          const featureValue = feature.get('value')
          const average = getAverage(valueArr)
          if (featureValue === average) return

          const lonArr = feature.get('lonArr')
          const latArr = feature.get('latArr')
          lonArr.push(point.longitude * 1)
          latArr.push(point.latitude * 1)

          feature.setProperties({
            value: average,
            longitude: getAverage(lonArr),
            latitude: getAverage(latArr)
          })
          feature.setStyle(function(item) {
            const text = item.get('value').toFixed(2)
            const color = (data.legendIndexRange.length ? getColorByRange(average, data.legendIndexRange) : getColorByValue(data.comparison, average, data.currentAirIndex))
            return new Style({
              fill: new Fill({
                color: color
              }),
              text: new Text({
                // 文字内容
                text: text,
                // 位置
                textAlign: 'center',
                // 基准线
                textBaseline: 'top',
                // 文字样式
                font: 'normal 12px SourceHanSansCN-Medium',
                fill: new Fill({
                  color: 'rgba(0, 0, 0, 1)'
                })
              })
            })
          })
          // 将涉及的方块feature存储起来
          if (data.featureArr.length > 0) {
            let include = false
            for (let i = 0; i < data.featureArr.length; i++) {
              if (data.featureArr[i].getId() === feature.getId()) {
                // 替换最新的值
                data.featureArr[i] = feature
                include = true
              }
            }
            if (!include) {
              data.featureArr.push(feature)
            }
          } else {
            data.featureArr.push(feature)
          }
        }
      })
    }

    // 因为对于地图渲染的压力过大，暂时弃用该方法
    // // 筛选出与测点有交集的网格 直播情况与回放会有所不同
    // function squareFilter(point) {
    //   const featureArr = data.featureArr
    //   // 先写死一个点位，后续该点位应取无人机传回的点位
    //   // const pt = turf.point([118.75906729285002, 31.825836584108633])
    //   const pt = turf.point([point.longitude * 1, point.latitude * 1])
    //   data.squareFeatures.forEach((e, index) => {
    //     // 判断点有没有落在feature中
    //     const isIn = turf.booleanPointInPolygon(pt, e)
    //     if (isIn) {
    //       const format = new GeoJSON()
    //       const olFeature = format.readFeature(e)
    //       const geom = olFeature.getGeometry().transform('EPSG:4326', 'EPSG:3857')
    //       olFeature.setGeometry(geom)

    //       // 获取点携带的检测值并计算

    //       //     // 判断
    //       //     olFeature.setId(index)

    //       //     const existArr = featureArr.filter(item => item.id_ === index)
    //       //     if (existArr.length > 0) { // 该网格已存在数组中，重新计算网格测值
    //       //       const exist = existArr[0]
    //       //       const existIndex = featureArr.indexOf(exist)
    //       //       e.valueArr.push(point[data.currentAirIndex] * 1)
    //       //       // 根据当前关注的值进行计算
    //       //       let sum = 0
    //       //       e.valueArr.forEach(value => {
    //       //         sum = sum + value
    //       //       })
    //       //       const averege = sum / e.valueArr.length
    //       //       featureArr[existIndex].aValue = averege
    //       //     } else {
    //       //       olFeature.aValue = point[data.currentAirIndex] * 1
    //       //       e.valueArr.push(point[data.currentAirIndex] * 1)
    //       //       featureArr.push(olFeature)
    //       //     }
    //     }
    //   })
    //   // drawFeature(featureArr)
    // }

    // 获取空气质量指标
    function getAirIndex() {
      getAirDataType().then(res => {
        if (res.code === 0) {
          data.airIndexList = res.data
          data.airIndexList.forEach(e => {
            const option = {
              label: e.name,
              value: e.dataType
            }
            data.selectOption.push(option)
          })
        }
      })
    }

    // // 获取渲染用的方块列表
    // function getSquareList(temp, list) {
    //   const n = data.n
    //   if ((list.length % n) === 0 && list.length > 0) {
    //     data.trackTemp = list.slice(temp * n, (temp + 1) * n)
    //     data.squareList.push(data.trackTemp)
    //     data.trackTemp = []
    //   }
    // }

    // 绘制feature
    function drawFeature(featureArr) {
      console.log('绘制feature')
      if (data.squareLayer) {
        data.map.removeLayer(data.squareLayer)
        data.squareLayer = null
      }
      const featureSource = new VectorSource({
        features: featureArr
      })
      data.featureSource = featureSource
      const layer = new VectorLayer({
        source: featureSource,
        // source: new VectorSource({
        //   features: featureArr
        //   // features:
        // }),
        visible: true,
        zIndex: 1,
        style: function(item) {
          return new Style({
            fill: new Fill({
              color: 'rgba(0,0,0,0)'
            })

          })
        }
      })
      data.map.addLayer(layer)
      data.squareLayer = layer

      // 绘制后添加点击事件
      data.map.on('click', (evt) => {
        squareClick(evt)
      })
    }

    // 方框点击事件
    function squareClick(event) {
      // const feature = data.map.forEachFeatureAtPixel(event.pixel,
      console.log('方框点击事件', data.map)
      data.map.forEachFeatureAtPixel(event.pixel,
        function(feature, layer) {
          const propsArr = feature.get('propsArr')
          // console.log(feature.id_)
          // 对于无数据的直接返回
          if (propsArr.length === 0) return

          const name = '数据点' + feature.get('id')
          console.log('点击数据点信息', feature.get('id'), feature)
          // 处理所有需要的数据获得平均值
          // 获取所有的指标
          const indexList = []
          data.airIndexList.forEach(index => {
            indexList.push({ name: index.name, type: index.dataType, unit: index?.unit })
          })
          // 加上高度、湿度、温度、经度、纬度
          // indexList.push({name：'altitude'}, 'humidity', 'temperature', 'longitude', 'latitude')
          indexList.unshift({ name: '高度', type: 'altitude', unit: 'm' },
            { name: '经度', type: 'longitude', unit: '°E' },
            { name: '纬度', type: 'latitude', unit: '°N' },
            { name: '湿度', type: 'humidity', unit: '%rh' })
          console.log('点详细参数', indexList, propsArr)
          // 获取该方块的所有平均值
          const averageProps = []
          indexList.forEach((i, index) => {
            const valueArr = []

            let currentIndex
            if (i.type === 'pm_2_5') {
              currentIndex = 'pm25'
            } else if (i.type === 'pm_10') {
              currentIndex = 'pm10'
            } else {
              currentIndex = i.type
            }

            propsArr.forEach(prop => {
              valueArr.push(prop[currentIndex] * 1)
            })
            // averageProps[i] = getAverage(valueArr)
            averageProps.push({ name: i.name, value: getAverage(valueArr), unit: i.unit, sort: index + 5 })
          })
          // 加上面积属性
          // averageProps.area = data.cellSide * data.cellSide
          averageProps.unshift({ name: '面积', value: data.cellSide * data.cellSide, unit: '㎡', sort: 1 })

          // 弹窗
          const coordinates = feature.get('geometry').flatCoordinates

          // 赋值
          data.squareInfo = { averageProps: averageProps, name: name }
          // 位置
          data.airInfoOverlay.setPosition(coordinates)
        })
    }
    // 创建弹窗
    // function createInfowindow(props, coordinates) {
    //   if (data.mountNode) {
    //     airInfowindowClose()
    //   }
    //   const app = createVNode(squareWindow, {
    //     info: props
    //   })
    //   data.mountNode = document.createElement('div')
    //   render(app, data.mountNode)
    //   document.body.appendChild(data.mountNode)

    //   data.airInfoOverlay = new Overlay({
    //     id: 'airInfo_overlay',
    //     element: document.getElementById('squareInfo'),
    //     offset: [10, 10]
    //   })
    //   data.map.addOverlay(data.airInfoOverlay)
    //   data.airInfoOverlay.setPosition(coordinates)
    //   data.airInfoOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1
    // }

    function airInfowindowClose() {
      // if (!data.mountNode) return
      // document.body.removeChild(data.mountNode)
      // data.mountNode = null
      // if (!data.airInfoOverlay) return
      // data.map.removeOverlay(data.airInfoOverlay)
      // data.airInfoOverlay = null
      data.squareInfo = { averageProps: null, name: null }
      data.airInfoOverlay.setPosition(null)
    }

    const getMapOptions = computed(() => {
      return {
        id: props.id
      }
    })

    /**
     *  初始化地图
     */
    const initMap = () => {
      console.log('initMap初始化地图')
      // 天地图影像图
      const tdtImgMap = new Tile({
        visible: true,
        source: new XYZ({
          crossOrigin: 'anonymous',
          projection: gcj02Mecator,
          url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=6&x={x}&y={y}&z={z}'
        })
      })

      data.view = new View({
        center: transform([118.773136, 31.828065], 'EPSG:4326', 'EPSG:3857'),
        zoom: 11,
        maxZoom: 17
      })
      data.map = new Map({
        // 地图容器
        target: props.id,
        view: data.view,
        layers: [tdtImgMap],
        controls: control.defaults({
          attribution: false,
          rotate: false,
          zoom: false
        })
      })

      drawAirport()
      if (inspectionType.value === 2) {
        getAirLine()
      } else {
        createSquareGrid()
      }

      data.legendIndexRange = data.comparison[data.currentAirIndex]

      // createSquareByPoint({ longitude: 118.7801087, latitude: 31.8270537 })
      // drawDrone(airport.value.longitude, airport.value.latitude)
      // legendIndex
      // 航线长度信息框

      // 添加网格属性框
      data.airInfoOverlay = new Overlay({
        id: 'airInfo_overlay',
        element: document.getElementById('squareInfo'),
        offset: [10, 10],
        className: 'grid-info ol-overlay-container ol-selectable'
      })
      data.map.addOverlay(data.airInfoOverlay)

      const legendOverlay = new Overlay({
        position: fromLonLat([23.3725, 48.208889]),
        id: 'legend-overlay',
        element: document.getElementById('colorLegend'),
        offset: [10, 10],
        className: 'color-legend ol-overlay-container ol-selectable'
      })
      data.map.addOverlay(legendOverlay)
    }

    /* 获取直播轨迹数据 */
    const getTrackData = async function(id) {
      console.log('获取直播数据轨迹')
      const res = await getFlightData(id)
      if (res.data.length === 0) return
      data.monitorInfo.height = res.data[0].latitude || 0
      console.log(' res.data', res.data)
      const trackList = res.data
      data.trackList = trackList
      return Promise.resolve({
        trackList
      })
    }
    // getTrackData(props.currentTask)

    const drawAirport = () => {
      console.log('drawAirport====', airport.value)
      if (!airport.value) return
      const lngLat = [
        parseFloat(airport.value.longitude),
        parseFloat(airport.value.latitude)
      ]
      const feature = new Feature({
        geometry: new Point(fromLonLat(lngLat))
      })
      // 要素设置样式
      feature.setStyle(geomStyles('airport'))
      // 要素设置id
      feature.setId(airport.value.id)
      // 添加矢量图层
      const airLayer = new VectorLayer({
        source: new VectorSource({
          features: [feature]
        }),
        visible: true,
        zIndex: 11
      })
      data.map.addLayer(airLayer)
      data.vectorLayers.push(airLayer)
      data.airportLayer = airLayer
    }

    // if (!data.map) {
    //   // data.trackTimer = setInterval(() => {
    //   //   getTrackData(taskId.value).then(({ trackList }) => {
    //   //     // 有数据了再画
    //   //     if (trackList.length > 1) {
    //   //       setLiveTrack(formatTradeList(trackList))
    //   //       clearInterval(data.trackTimer)
    //   //       data.trackTimer = null
    //   //     }
    //   //   })
    //   // }, 2000)
    //   if (type.value === 'live') {
    //     data.trackTimer = setInterval(() => {
    //       getTrackData(taskId.value).then(({ trackList }) => {
    //         // 有数据了再画
    //         if (trackList.length > 1) {
    //           setLiveTrack(formatTradeList(trackList))
    //           clearInterval(data.trackTimer)
    //           data.trackTimer = null
    //         }
    //       })
    //     }, 2000)
    //   } else {
    //     airData()
    //     getTrackData(taskId.value).then(({ trackList }) => {
    //       data.trackList = trackList
    //       data.trackInfo = initTrack(formatTradeList(trackList), 'liveTrackLayer', 'route')
    //     })
    //   }
    // }

    // setup执行
    function onSetup() {
      if (type.value === 'live') {
        data.trackTimer = setInterval(() => {
          getTrackData(taskId.value).then(res => {
            console.log('第七个', res)
            // 有数据了再画
            if (res?.trackList.length > 1) {
              setLiveTrack(formatTradeList(res.trackList))
              clearInterval(data.trackTimer)
              data.trackTimer = null
            }
          })
        }, 2000)
      } else {
        airData()
        console.log('第八个')

        getTrackData(taskId.value).then((res) => {
          console.log('第八个res', res)
          if (res == undefined) return
          console.log('第八个，走到这里')

          data.trackList = res.trackList
          data.trackInfo = initTrack(formatTradeList(data.trackList), 'liveTrackLayer', 'route')
        })
      }
    }
    onSetup()

    /* 加载实时轨迹 */
    const setLiveTrack = function(hisTrackList) {
      var changeTrack
      console.log('加载实时轨迹')
      data.trackInfo = initTrack(hisTrackList, 'liveTrackLayer', 'route')
      if (data.trackInfo.vectorLayer) {
        data.liveTrackLayer.on('change', changeTrack)
      }

      /* 轨迹改变 */
      changeTrack = (event) => {
        try {
          const vectorContext = getVectorContext(event)
          vectorContext.setIndex(100)
          vectorContext.setStyle(styleList['geoMarker'])
          VectorContext.drawGeometry(data.trackInfo.position)
          vectorContext.drawGeometry(data.trackInfo.route)
          data.map.render()
        } catch {
          console.log(event)
        }
      }

      // 两秒钟获取一次数据

      data.socket = setInterval(() => {
        getTrackData(taskId.value).then((res) => {
          console.log('第九个', res)

          if (!res.trackList || res.trackList.length === 0) {
            console.log('轨迹列表为空，请等待机场准备或联系管理员')
            return
          }
          const len = res.trackList.length
          const obj = res.trackList[len - 1]
          const coordinate = fromLonLat([obj?.lng, obj?.lat])
          // const warningLngLat = turf.point(data.warningLngLat)
          // const uavLngLat = turf.point([parseFloat(obj?.lng), parseFloat(obj?.lat)])
          // const distance = turf.distance(warningLngLat, uavLngLat).toFixed(2)
          // emit('distance', distance)
          if (data.trackInfo) {
            data.trackInfo.route.appendCoordinate(coordinate)
            data.trackInfo.vectorLayer.getSource().changed()
            data.trackInfo.position.setCoordinates(coordinate)
          }
        })
        airData()
      }, 2000)
    }
    let isFirstInterval = true
    // 获取大气监测数据
    function airData() {
      getAirtData(taskId.value).then(res => {
        console.log('获取大气监测数据', res)
        if (res?.data.length === 0 || !res?.data) {
          // console.log('大气监测数据为空，请联系管理员，任务id为', taskId.value)
          return
        }
        if (isFirstInterval) {
          data.airData = res.data
          res.data.forEach(e => {
            squareFilter(e)
          })
          isFirstInterval = false
        }

        if (type.value === 'live') {
          squareFilter(res.data[0])
          data.airData = res.data
        }
        // else {
        //   res.data.forEach(e => {
        //     data.airData = res.data
        //     squareFilter(e)
        //   })
        // }

        setTimeout(() => {
          handleSquareGrid()
        })
      })
    }
    // 手动触发绘制
    function handleSquareGrid() {
      console.log('手动触发绘制')
      createSquareGrid()
      if (!data.airData) return
      airInfowindowClose()
      data.featureArr.length = 0
      data.airData.forEach(e => {
        squareFilter(e)
      })
    }

    // 计算数字数组的平均值
    function getAverage(arr) {
      let num = 0
      arr.forEach(e => {
        num = num + e
      })
      const average = num / arr.length
      return average
    }

    /* 初始化轨迹 */
    const initTrack = function(coordinate, layer, routeType) {
      console.log('初始化轨迹')
      let vectorLayer = null
      // 路线
      const route = new LineString(coordinate)
      const routeFeature = new Feature({
        type: routeType,
        geometry: route
      })
      const endMarker = new Feature({
        type: 'icon',
        geometry: new Point(route.getLastCoordinate())
      })
      const position = endMarker.getGeometry().clone()
      if (routeType === 'route') { // 轨迹数据
        const geoMarker = new Feature({
          type: 'geoMarker',
          geometry: position
        })
        geoMarker.setProperties({ type: 'geoMarker' }, false)
        if (data.liveTrackLayer) {
          data.liveTrackLayer.setSource(
            new VectorSource({
              features: [geoMarker, routeFeature]
            })
          )
          vectorLayer = data.liveTrackLayer
        } else {
          vectorLayer = new VectorLayer({
            source: new VectorSource({
              features: [geoMarker, routeFeature]
            }),
            style: function(feature) {
              return styleList[feature.get('type')]
            },
            zIndex: 12
          })
        }
        data[layer] = vectorLayer
        data.map.addLayer(data[layer])
        data.view.fit(route, { padding: [30, 30, 30, 30] })
        if (type.value === 'return') {
          if (!coordinate?.length) return
          const coordLength = coordinate?.length
          const moveFeature = (event) => {
            /* 计算飞行的百分比 */
            const percent = props.videoInfo.currentTime / props.videoInfo.duration
            const coorIndex = Math.floor(coordLength * percent)
            let currentCoordinate
            if (coorIndex >= 1) {
              currentCoordinate = coordinate[coorIndex - 1]
            } else {
              currentCoordinate = coordinate[coorIndex]
            }
            position.setCoordinates(currentCoordinate)
            geoMarker.setGeometry(null)
            const vectorContext = getVectorContext(event)
            vectorContext.setStyle(styleList['geoMarker'])
            vectorContext.drawGeometry(position)
            data.map.render()
          }
          vectorLayer.on('postrender', moveFeature.bind())
        }
        return {
          vectorLayer,
          geoMarker,
          route,
          position
        }
      }
    }

    // /* 处理轨迹列表 */
    const formatTradeList = function(trackList) {
      console.log('处理轨迹列表')
      return trackList.map((item) =>
        fromLonLat([parseFloat(item.lng), parseFloat(item.lat)])
      )
    }
    /**
     *  获取打开overlay中最大的 z-index
     */
    const getMaxZOverlay = () => {
      let maxZIndex = 0
      const overlays = data.map.getOverlays().array_
      if (overlays.length) {
        overlays.forEach((item) => {
          const zIndex = item.getElement().parentElement.style.zIndex
          if (zIndex > maxZIndex) {
            maxZIndex = zIndex
          }
        })
      }
      return maxZIndex
    }

    // 结束直播飞行
    const endLiveFly = () => {
      if (data.socket) {
        clearInterval(data.socket)
        data.socket = null
      }
      data.vectorLayers.forEach((layer) => {
        if (layer) {
          data.map.removeLayer(layer)
        }
      })
      data.vectorLayers.length = 0
    }

    // 计算报告所需的数据
    function getReportData() {
      const featureArr = data.featureArr

      const inspectionId = taskId.value
      const airDataType = data.currentAirIndex
      const gridSize = data.cellSide + 'm ×' + data.cellSide + 'm (' + data.cellSide * data.cellSide + '㎡)'
      const averageGridSize = data.cellSide + 'm ×' + data.cellSide + 'm (' + data.cellSide * data.cellSide + '㎡)'
      // const averageGridSize = data.cellSide * data.cellSide + '㎡'
      const gridArea = data.cellSide * data.cellSide * featureArr.length + '㎡'
      const centerPointLongitudeAndLatitude = data.gridCenter
      let gridConcentrationMax = 0
      let gridConcentrationMix = featureArr[0]?.get('value')
      let maxCord = ''
      let minCord = ''
      let unit = 'μg/m³'
      featureArr.forEach(feature => {
        const gridValue = feature?.get('value')
        // gridConcentrationMax = gridConcentrationMax < gridValue ? gridValue : gridConcentrationMax
        // gridConcentrationMix = gridConcentrationMix > gridValue ? gridValue : gridConcentrationMix

        if (gridConcentrationMax <= gridValue) {
          gridConcentrationMax = gridValue
          maxCord = feature?.get('longitude') + 'E,' + feature?.get('latitude') + 'N'
        }

        if (gridConcentrationMix >= gridValue) {
          gridConcentrationMix = gridValue
          minCord = feature?.get('longitude') + 'E,' + feature?.get('latitude') + 'N'
        }
      })
      if (airDataType === 'co') {
        unit = 'mg/m³'
      } else if (airDataType === 'vocs') {
        unit = 'ppm'
      }
      gridConcentrationMax = gridConcentrationMax + ` ${unit} (${maxCord})`
      gridConcentrationMix = gridConcentrationMix + ` ${unit} (${minCord})`

      const params = {
        inspectionId,
        airDataType,
        gridSize,
        averageGridSize,
        gridArea,
        centerPointLongitudeAndLatitude,
        gridConcentrationMax,
        gridConcentrationMix
      }

      return params
    }
    // 显示隐藏图层
    function setLayerVisible(layer, visible) {
      if (layer) {
        layer.setVisible(visible)
      }
    }
    // 获取图层范围并定位
    const fitLayer = (layer) => {
      if (layer) {
        const layerExtent = layer.getSource().getExtent()
        data.view.fit(layerExtent, {
          padding: [20, 20, 20, 20]
        })
      }
    }
    // 获取图片
    function getReportImg() {
      map2Png()
    }

    // 上传
    const uploadImages = function(list) {
      getOssAuth().then(res => {
        const client = new OSS({
          timeout: 600000,
          region: 'oss-cn-shanghai',
          secure: true,
          accessKeyId: res.data.accessKeyId,
          accessKeySecret: res.data.accessKeySecret,
          stsToken: res.data.securityToken,
          bucket: 'ta-tech-image'
        })
        // 上传图片
        const todos = []
        list.forEach(item => {
          todos.push(uploadOss(client, item))
        })
        Promise.all(todos).then(res => {
          if (res) {
            const params = getReportData()
            res.forEach(i => {
              params[i.name] = i.value
            })
            downLoadReport(params)
          }
        })

        // uploadOss(client, file).then(res => {
        //   data.ossUrl = res
        // })
        // uploadOss(client, file)
      })
    }

    const dataURLtoFile = (dataUrl, fileName = 'mark.png') => {
      var arr = dataUrl?.split(',')
      var mime = arr && arr[0]?.match(/:(.*?);/)[1]
      var bstr = arr && atob(arr[1])
      var mime = arr && arr[0]?.match(/:(.*?);/)[1]
      var bstr = arr && atob(arr[1])
      var n = bstr?.length
      var u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], fileName, { type: mime })
    }
    // 获取oss鉴权
    function upload(file) {
      getOssAuth().then(res => {
        const client = new OSS({
          timeout: 600000,
          region: 'oss-cn-shanghai',
          secure: true,
          accessKeyId: res.data.accessKeyId,
          accessKeySecret: res.data.accessKeySecret,
          stsToken: res.data.securityToken,
          bucket: 'ta-tech-image'
        })
      })
    }

    const uploadOss = (client, item) => {
      const file = item.value
      // const file = files.file
      return new Promise((resolve, reject) => {
        /* 生成随机文件名称 */
        const randomString = Math.random().toString(36).slice(2)
        const suffix = '.png'
        const timestamp = new Date().getTime()
        const objectName = `imagedir/${randomString}_${timestamp}${suffix}`
        /* 上传文件至oss */
        client.put(objectName, dataURLtoFile(file))
          .then((res) => {
            resolve({ name: item.name, value: res.url })
            // const prams = getReportData()
            // prams.ossUrl = res.url
            // exportReport(prams).then(
            //   reportRes => {
            //     if (reportRes.code === 0) {
            //       window.open(reportRes.data) // todo
            //     }
            //     // data.trackInfo.vectorLayer.setVisible(true)
            //     // data.airportLayer.setVisible(true)
            //   }
            // )
          })
          .catch((err) => {
            resolve('error')
            console.log(err)
          })
      })
    }

    // 下载报告
    const downLoadReport = function(params) {
      exportReport(params).then(
        reportRes => {
          if (reportRes.code === 0) {
            window.open(reportRes.data) // todo
          }
        }
      )
    }

    watch(() => props.mainScreen, newVal => {
      data.mainScreen = newVal
    })

    onMounted(() => {
      initMap()
      getAirIndex()
      if (props.mainScreen) {
        data.mainScreen = props.mainScreen
      }
    })

    onBeforeUnmount(() => {
      if (data.socket) {
        clearInterval(data.socket)
        data.socket = null
      }
      if (data.trackTimer) {
        clearInterval(data.trackTimer)
        data.trackTimer = null
      }
    })

    return {
      ...toRefs(data),
      getMapOptions,
      endLiveFly,
      initTrack,
      getReportData,
      getReportImg,
      changeRangeIndex,
      closeRangeIndex,
      map2Png,
      airInfowindowClose
    }
  }
}
</script>

<style lang="scss" scoped>
* {
  user-select: none;
}

.container {
  width: 100vw;
  height: 100vh;
  position: relative;
  overflow: hidden;
}

.map-container {
  position: absolute;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: 0px;

  ::v-deep(.color-legend)  {
    right: 20px;
    bottom: 40px;
    transform: none !important;
    z-index: 10;
  }

  ::v-deep(.grid-info)  {
    z-index: 999;
  }
}

.indexSelector {
  position: relative;
  width: 200px;
  // left: 1200px;
  left: 76%;
  top: 10px;
  z-index: 100;
}
@media screen and (max-width: 1700px) {
  .indexSelector {
    left: 68% !important;
  }
}

</style>
